package com.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.task.entity.Chunk;
import com.task.mapper.ChunkMapper;
import com.task.service.ChunkService;
import com.task.util.ChunkResult;
import com.task.util.FileInfoUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author Huzz
 * @since 2021-12-29
 */
@Slf4j
@Service
public class ChunkServiceImpl extends ServiceImpl<ChunkMapper, Chunk> implements ChunkService {

    @Value("${qingshu.resource.save-path}")
    private String uploadFolder;
    @Autowired
    private ChunkMapper chunkInfoMapper;

    /**
     * 校验当前文件
     * @param response
     * @return 秒传？续传？新传？
     */
    @Override
    public ChunkResult checkChunkState(Chunk chunk, HttpServletResponse response) {
        // 转换为保存的文件名称形式
        String asHex = DigestUtils.md5DigestAsHex(chunk.getFilename().getBytes(StandardCharsets.UTF_8));
        String suffix = chunk.getFilename().substring(chunk.getFilename().lastIndexOf("."));

        ChunkResult chunkResult = new ChunkResult();
        String file = uploadFolder + File.separator + chunk.getIdentifier() + File.separator + asHex + suffix;
        if(FileInfoUtils.fileExists(file)) {
            chunkResult.setSkipUpload(true);
            chunkResult.setLocation(file);
            response.setStatus(HttpServletResponse.SC_OK);
            chunkResult.setMessage("完整文件已存在，直接跳过上传，实现秒传");
            return chunkResult;
        }
        QueryWrapper<Chunk> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Chunk::getFilename, asHex + suffix);
        wrapper.lambda().eq(Chunk::getIdentifier, chunk.getIdentifier());
        List<Chunk> list = chunkInfoMapper.selectList(wrapper);
        List<Integer> chunkNumberList = new ArrayList<>();
        list.forEach(e -> chunkNumberList.add(e.getChunkNumber()));
        if (list !=null && list.size() > 0) {
            chunkResult.setSkipUpload(false);
            chunkResult.setUploadedChunks(chunkNumberList);
            response.setStatus(HttpServletResponse.SC_OK);
            chunkResult.setMessage("部分文件块已存在，继续上传剩余文件块，实现断点续传");
            return chunkResult;
        }
        return chunkResult;
    }

    /**
     * 写文件
     * @param chunk
     * @return
     */
    @Override
    public Integer uploadFile(Chunk chunk) {
        String asHex = DigestUtils.md5DigestAsHex(chunk.getFilename().getBytes(StandardCharsets.UTF_8));
        String suffix = chunk.getFilename().substring(chunk.getFilename().lastIndexOf("."));
        chunk.setFilename(asHex + suffix);
        Integer apiRlt = HttpServletResponse.SC_OK;
        MultipartFile file = chunk.getUpFile();
        try {
            byte[] bytes = file.getBytes();
            Path path = Paths.get(FileInfoUtils.generatePath(uploadFolder, chunk));
            Files.write(path, bytes);

            if(chunkInfoMapper.insert(chunk) < 0){
                apiRlt = HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE;
            }
        } catch (IOException e) {
            log.error("写文件出错:");
            log.error(e.getMessage());
            apiRlt = HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE;
        }
        log.info("分片上传返回结果: "+apiRlt);
        return apiRlt;
    }

}
